#include "grflib_stdafx.h"
#include "../include/AxesMesh.h"
#include "../include/VertexFormat.h"
#include "../include/D3D10Engine.h"

using namespace grflib::engine::core;
using namespace grflib::engine::aux;
using namespace grflib::engine;


CAxesMesh::CAxesMesh()
{
	m_bbox.Cube(0.0f);
	CreateAxesMaterial();
	CreateAxesMesh();
	m_nGroups = 3;
}

void CAxesMesh::SetEffect(const std::string &effectName)
{
	SetEffectTechnique(effectName, "Color");
}

CAxesMesh::~CAxesMesh()
{
	OnDestroy();
}

BBox<float> &CAxesMesh::GetBoundingBox()
{
	return m_bbox;
}

void CAxesMesh::CreateAxesMesh()
{
	static const UINT nVertex = 21;
	static const UINT nIndex = 18;

	static float faVertex[nVertex * 3] = 
	{
		//x axis
		0.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
		1.0f, -0.05f, 0.05f,
		1.0f, 0.05f, 0.05f,
		1.0f, 0.05f, -0.05f,
		1.0f, -0.05f, -0.05f,
		1.15f, 0.0f, 0.0f,
		//y axis,
		0.0f, 0.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		-0.05f, 1.0f, 0.05f,
		0.05f, 1.0f, 0.05f,
		0.05f, 1.0f, -0.05f,
		-0.05f, 1.0f, -0.05f,
		0.0f, 1.15f, 0.0f,
		//z axis
		0.0f, 0.0f, 0.0f,
		0.0f, 0.0f, 1.0f,
		-0.05f, 0.05f, 1.0f,
		0.05f, 0.05f, 1.0f,
		0.05f, -0.05f, 1.0f,
		-0.05f, -0.05f, 1.0f,
		0.0f, 0.0f, 1.15f
	};

	static UINT faIndex[nIndex /** 3*/] = 
	{0, 1, 2, 3, 3, 4, 4, 5, 5, 2, 5, 6, 4, 6, 3, 6, 2, 6};

	boost::shared_ptr< std::vector<float> > pVertices;
	boost::shared_ptr< std::vector<DWORD> > pIndices;

	boost::shared_ptr<std::vector<D3D10_INPUT_ELEMENT_DESC>> pElements;
	std::size_t stride;

	for (UINT group = 0; group < 3; group++)
	{
		pVertices.reset( new std::vector<float> );
		pIndices.reset( new std::vector<DWORD> );
		pElements.reset( new std::vector<D3D10_INPUT_ELEMENT_DESC> );
		vertex_format::Mapping(*pElements, stride);

		for (UINT i = 0; i < nVertex; i++)
			pVertices->push_back(faVertex[group * nVertex + i]);

		for (UINT i = 0; i < nIndex; i++)
			pIndices->push_back(faIndex[i]);

		m_vertexVec.push_back(pVertices);
		m_indexVec.push_back(pIndices);
		m_primitiveTopology.push_back(D3D10_PRIMITIVE_TOPOLOGY_LINELIST);
		m_vertexLayouts.push_back(pElements);
		m_vertexStride.push_back(stride);
	}

	m_materials[0] = "engine:material_pure_red";
	m_materials[1] = "engine:material_pure_green";
	m_materials[2] = "engine:material_pure_blue";
}

void CAxesMesh::CreateAxesMaterial()
{
	boost::shared_ptr<CMaterial> pMaterial = boost::dynamic_pointer_cast<CMaterial>(_ResrcMan.FindObj("engine:material_pure_red"));
	if (!pMaterial)
	{
		pMaterial.reset(new CMaterial);
		pMaterial->diffuse[0] = 1.0f;
		pMaterial->diffuse[1] = 0.0f;
		pMaterial->diffuse[2] = 0.0f;
		_ResrcMan.AddObj("engine:material_pure_red", boost::dynamic_pointer_cast<IResource>(pMaterial));
	}

	pMaterial = boost::dynamic_pointer_cast<CMaterial>(_ResrcMan.FindObj("engine:material_pure_green"));
	if (!pMaterial)
	{
		pMaterial.reset(new CMaterial);
		pMaterial->diffuse[0] = 0.0f;
		pMaterial->diffuse[1] = 1.0f;
		pMaterial->diffuse[2] = 0.0f;
		_ResrcMan.AddObj("engine:material_pure_green", boost::dynamic_pointer_cast<IResource>(pMaterial));
	}

	pMaterial = boost::dynamic_pointer_cast<CMaterial>(_ResrcMan.FindObj("engine:material_pure_blue"));
	if (!pMaterial)
	{
		pMaterial.reset(new CMaterial);
		pMaterial->diffuse[0] = 0.0f;
		pMaterial->diffuse[1] = 0.0f;
		pMaterial->diffuse[2] = 1.0f;
		_ResrcMan.AddObj("engine:material_pure_blue", boost::dynamic_pointer_cast<IResource>(pMaterial));
	}
}